package com.boot.service.impl;

import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.boot.ao.auth.LoginAO;
import com.boot.ao.sysuser.AddSysUserAO;
import com.boot.ao.sysuser.UpdateSysUserAO;
import com.boot.common.exception.UnAuthorizedException;
import com.boot.common.po.Result;
import com.boot.common.po.StatusCodeEnum;
import com.boot.dto.auth.UserRoleDTO;
import com.boot.entity.SysUser;
import com.boot.mapper.SysUserMapper;
import com.boot.service.SysUserService;
import com.boot.vo.auth.LoginVo;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import javax.naming.AuthenticationException;
import java.util.Date;
import java.util.List;

/**
 * @Description: 业务层
 * @Author: zk
 * @Date: 2021/4/14 上午10:35
 **/
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {

    @Resource
    private SysUserMapper sysUserMapper;

    @Override
    public List<SysUser> getList() {
        return sysUserMapper.queryAll();
    }

    @Override
    public SysUser getUserById(Long id) {
        return sysUserMapper.selectById(id);
    }

    public void add(AddSysUserAO addSysUserAO) {
        SysUser sysUser = new SysUser();
        BeanUtils.copyProperties(addSysUserAO, sysUser);
        sysUserMapper.insert(sysUser);
    }

    /**
     * @description: 修改
     * @author: zk
     * @date: 2021/4/14 下午2:34
     * @param updateSysUserAO:
     * @return void
     * @throws
     **/
    @Override
    public void update(UpdateSysUserAO updateSysUserAO) {
        SysUser sysUser = new SysUser();
        BeanUtils.copyProperties(updateSysUserAO, sysUser);
        sysUserMapper.updateById(sysUser);
    }

    /**
     * @description: 删除
     * @author: zk
     * @date: 2021/4/14 下午2:34
     * @param id:
     * @return void
     * @throws
     **/
    @Override
    public void delete(Long id) {
        sysUserMapper.deleteById(id);
    }

    @Override
    public void insert(SysUser sysUser) {
        sysUserMapper.insert(sysUser);
    }

    /**
     * @description: 登陆
     * @author: zhangkai
     * @date: 2021/4/15 下午2:55
     * @param loginAO:
     * @return com.boot.common.po.Result
     * @throws
     **/
    @Override
    public Result login(LoginAO loginAO) {
        // 1、查询当前用户的账号是否存在
        SysUser user = sysUserMapper.selectOne(new QueryWrapper<SysUser>().lambda().eq(SysUser::getUsername, loginAO.getUsername()));
        if (StringUtils.isEmpty(user))
            throw new UnAuthorizedException(StatusCodeEnum.USER_NOT_EXIST.getCode(), StatusCodeEnum.USER_NOT_EXIST.getContent());

        // 2、验证密码是否正确
        if (!user.getPassword().equals(DigestUtils.md5DigestAsHex(loginAO.getPassword().getBytes())))
            throw new UnAuthorizedException(StatusCodeEnum.LOGINE_RROR.getCode(), StatusCodeEnum.LOGINE_RROR.getContent());

        // 自定义生成Token，所以需要字段调用生成token并返给前端
        // 这里可以根据用户信息查询对应的角色信息，这里为了简单，我直接设置个空list

        List<UserRoleDTO> roles = sysUserMapper.selectRolesByUserId(user.getId());

        String subject = loginAO.getUsername() + "-" + roles;
        String token= JWT.create()
                .withSubject(subject)
                .withAudience(String.valueOf(user.getId()))
                //设置过期时间 60秒(这里为了方便测试，所以设置了1分钟的过期时间，实际项目需要根据自己的情况修改)
                .withExpiresAt(new Date(System.currentTimeMillis() + 1000 * 60))
                .sign(Algorithm.HMAC256(user.getPassword()));
//        String token = JWT.builder()
//                .setSubject(subject)
//                // 设置过期时间 60秒(这里为了方便测试，所以设置了1分钟的过期时间，实际项目需要根据自己的情况修改)
//                .setExpiration(new Date(System.currentTimeMillis() + 1000 * 60))
//                //采用什么算法是可以自己选择的，不一定非要采用HS512
//                .signWith(SignatureAlgorithm.HS512, Constants.SIGNING_KEY)
//                .compact();
        return Result.success("登陆成功", LoginVo.builder().token(token).build());
    }
}
